<template>
  <div v-if="theFormItemList.length > 0" class="custom-search" :style="{ '--columns': columns }">
    <slot v-if="title" name="title">
      <span class="title">{{ title }}</span>
    </slot>
    <el-form ref="rulesForm" :model="form" width="100%" :label-width="labelWidth" status-icon>
      <el-form-item v-for="item in theFormItemList" :key="item.label" :label="item.label" :prop="props.required ? item.name : ''" :class="item.name" :rules="item.rules || []">
        <el-input v-if="item.widget == 'input'" v-model="form[item.name]" :placeholder="'请输入' + item.label" clearable @clear="search" />
        <template v-if="item.widget == 'dropdownSelect'">
          <el-popover placement="bottom" class="search-popover" :width="400" trigger="click" :visible="activePopover == item.name + 'Popover'">
            <el-table v-loading="loading" :data="item.options ? item.options : optionsData[item.name]" style="width: 100%" height="200px" @row-click="getOptions(item, $event, 2)">
              <el-table-column prop="zddm" label="字典代码" width="170" />
              <el-table-column prop="zdzw" label="字典中文" width="200" />
            </el-table>
            <div class="bth">
              <el-button type="primary" @click.stop="reselect">
                <el-icon><Refresh /></el-icon>

                重选</el-button
              >
              <el-button type="primary" plain @click.stop="cancelSelect">取消</el-button>
            </div>
            <template #reference>
              <el-select v-model="form[item.name]" :placeholder="'请选择' + item.label" @click.stop="getOptions(item)" clearable @clear="search">
                <template #label>
                  {{ (optionsData[item.name] && optionsData[item.name][0]?.zdzw) || '请选择' }}
                </template>
              </el-select>
            </template>
          </el-popover>
        </template>

        <el-date-picker
          v-if="item.widget == 'datePicker'"
          v-model="form[item.name]"
          :type="item.type == 'daterange' ? 'daterange' : 'date'"
          :placeholder="'请选择' + item.label"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          range-separator="至"
          :value-format="item['value-format'] || 'YYYY-MM-DD'"
          :shortcuts="item.shortcuts"
          clearable
          @clear="search"
        />
      </el-form-item>
      <el-form-item label="" class="search-btn">
        <el-button type="primary" @click="search">
          <el-icon size="14"><Search /></el-icon>查询</el-button
        >
        <el-button v-if="showRest" type="primary" plain class="reset" @click="reset">
          <el-icon size="16"><Refresh /></el-icon> 重置
        </el-button>
        <slot name="moreHandle"> </slot>
      </el-form-item>
    </el-form>
    <slot name="right"> </slot>
  </div>
</template>

<script setup name="CustomSearch">
import { ref, reactive, onMounted, computed, watch, defineModel, defineExpose, onBeforeUnmount, nextTick } from 'vue'
import { http } from '@/utils/index.js'
import { stores } from '@/stores/index.js'
// const formItemList = defineModel('formItemList', { default: [] }) //低代码数据格式，会直接传入搜索项
const form = defineModel('form', { default: {} })
const userStore = stores.useUserStore()
console.log(userStore.userInfor.dwdm)
const dynamicParamsStore = stores.useDynamicParamsStore()
const props = defineProps({
  //是否低代码模式,低代码模式下会传入formItemList，非低代码模式下根据form传入的值生成formItemList
  lowcode: {
    type: Boolean,
    default: false
  },
  formItemList: {
    type: Array,
    default: () => {
      return []
    }
  },
  title: {
    type: [String],
    default: ''
  },
  api: {
    //默认低代码请求数据的接口
    type: String,
    default: '/dict/codeservice/code'
  },
  labelWidth: {
    type: String,
    default: '120rem'
  },
  itemHeight: {
    //el-form-item 的高度
    type: String,
    default: '36rem'
  },
  fontSize: {
    //el-form-item 字体大小
    type: String,
    default: '14rem'
  },
  fontColro: {
    //el-form-item 字体颜色
    type: String,
    default: '#606266'
  },
  //每行显示几个表单项
  columns: {
    type: [String, Number],
    default: 5
  },
  showRest: {
    type: Boolean,
    default: true
  }
})

//form最开始传入的数据
const originData = JSON.stringify(form.value)
const theFormItemList = ref(props.formItemList)
const loading = ref(false)
// const visible = ref(true)
const activeSelect = ref({})
const activePopover = ref('') //当前激活的select下拉框
const emit = defineEmits(['getData', 'search'])
//el-select或el-cascader 类型的 option选项数据
const optionsData = ref({})
if (!props.lowcode) {
  creatFormItemList()
}

//点击下拉框获取选项数据
const getOptions = (selectConfig, row = {}, model = 1) => {
  console.log(selectConfig)

  activeSelect.value = selectConfig

  activePopover.value = selectConfig.name + 'Popover'

  //el-select预设了选项值
  if (selectConfig.options && row) {
    optionsData.value[selectConfig.name] = []
    optionsData.value[selectConfig.name].push(row)
    form.value[selectConfig.name] = row.zddm
    if (Object.keys(row).length != 0) {
      activePopover.value = ''
    }
  } else {
    //普通接口请求数据
    if (selectConfig.api) {
      //从接口请求数据
      if (!row.zddm) {
        loading.value = true
        const params = JSON.parse(JSON.stringify(selectConfig.params))
        //匹配请求参数中以大括号包裹的动态参数{xxx}
        for (const key in params) {
          const dynamicpParam = /{([^}]+)}/.exec(params[key])?.[1]
          if (dynamicpParam) {
            if (dynamicpParam == 'dwdm') {
              params[key] = dynamicParamsStore.dynamicParams['treeNode']?.zddm || null
            } else {
              params[key] = dynamicParamsStore.dynamicParams[dynamicpParam] || null
            }
          }
        }
        http(selectConfig.api, selectConfig.method || 'get', params)
          .then((res) => {
            optionsData.value[selectConfig.name] = res.data || res.data.record || []
          })
          .finally(() => {
            loading.value = false
          })
      } else {
        //从接口返回的数据中筛选数据
        if (row.children) {
          optionsData.value[selectConfig.name] = optionsData.value[selectConfig.name].find((item) => item.zddm == row.zddm).children
        } else {
          optionsData.value[selectConfig.name] = []
          optionsData.value[selectConfig.name].push(row)
          // form.value[selectConfig.name] = selectConfig.valueType ? optionsData.value[selectConfig.name][0][selectConfig.valueType] : optionsData.value[selectConfig.name][0].zddm
          form.value[selectConfig.name] = optionsData.value[selectConfig.name][0].zddm
          activePopover.value = ''
        }
      }
    } else {
      //低代码数据格式请求数据
      loading.value = true
      http(props.api, 'post', {
        codeTableName: optionsData.downSelectDataName,
        inputValue: row.zddm || '',
        unit: userStore.userInfor.dwdm,
        model: model,
        rules: '',
        dwlx: userStore.userInfor.dwlx
      })
        .then((res) => {
          optionsData.value[optionsData.name] = res.data || res.data.record || []
          if (optionsData.value[optionsData.name].length == 1) {
            form.value[optionsData.name] = optionsData.value[optionsData.name][0].zddm
            activePopover.value = ''
          }
        })
        .finally(() => {
          loading.value = false
        })
    }
  }
}

onMounted(() => {
  //如果select 类型设置了默认值
  theFormItemList.value.forEach((item) => {
    if (item.widget == 'dropdownSelect' && item.options && item.defultValue) {
      const option = item.options.find((v) => v.zddm == item.defultValue)
      if (option) {
        optionsData.value[item.name] = []
        optionsData.value[item.name].push(option)
      }
    }
  })
  // addEventListener('click', hidPopover)
})
onBeforeUnmount(() => {
  // removeEventListener("click", hidPopover);
})

const formatParams = () => {
  const params = JSON.parse(JSON.stringify(form.value))

  for (const key in params) {
    const item = theFormItemList.value.find((item) => item.name == key)
    if (item.type == 'daterange') {
      if (Array.isArray(params[key])) {
        params[key + '_BEGIN'] = params[key][0]
        params[key + '_END'] = params[key][1]
      } else {
        params[key + '_BEGIN'] = ''
        params[key + '_END'] = ''
      }
      delete params[key]
    }
  }
  return params
}
const search = () => {
  nextTick(() => {
    emit('search', formatParams())
  })
}
const reset = () => {
  form.value = JSON.parse(originData)
  nextTick(() => {
    search()
  })
}
const reselect = () => {
  getOptions(activeSelect.value)
}
const cancelSelect = () => {
  console.log('cancelSelect')
  activePopover.value = ''
}
const hidPopover = () => {
  console.log(999)
  activePopover.value = ''
}
//通过属性值找对应的对象(属性值必须唯一)
function findByKey(key, arr) {
  let obj = {}
  todo(key, arr)
  function todo(key, arr) {
    arr.find((item) => {
      if (item.children) {
        todo(key, item.children)
      } else {
        if (item.zddm == key) {
          obj = item
          return
        }
      }
    })
  }
  return obj
}
//非低代码模式下，根据传入的form生成搜索项
function creatFormItemList() {
  const files = import.meta.glob('./type/*.js', { eager: true })
  let fieldList = []
  for (const key in files) {
    fieldList = fieldList.concat(files[key].default)
  }

  for (const key in form.value) {
    //根据key值找对应的配置项
    let formItem = fieldList.find((v) => v.name == key)
    if (formItem) {
      formItem = JSON.parse(JSON.stringify(formItem))
      //搜索选项设置了默认值
      if (form.value[key]) {
        formItem.defultValue = form.value[key]
      }
      //需要立即请求数据
      if (formItem.immediate === true) {
        getOptionsNow(formItem)
      }
      //添加时间快捷选择
      if (formItem.widget == 'datePicker' && formItem.type == 'daterange') {
        formItem.shortcuts = [
          {
            text: '前一周',
            value: () => {
              const end = new Date()
              const start = new Date()
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
              return [start, end]
            }
          },
          {
            text: '前一个月',
            value: () => {
              const end = new Date()
              const start = new Date()
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
              return [start, end]
            }
          },
          {
            text: '前三个月',
            value: () => {
              const end = new Date()
              const start = new Date()
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
              return [start, end]
            }
          }
        ]
      }
      theFormItemList.value.push(formItem)
    }
  }
}
//立即请求下拉框选项数据（非手动点击下拉框,下拉框需要有一个默认值的场景）
function getOptionsNow(selectConfig) {
  const params = JSON.parse(JSON.stringify(selectConfig.params))
  //匹配请求参数中以大括号包裹的动态参数{xxx}
  for (const key in params) {
    const dynamicpParam = /{([^}]+)}/.exec(params[key])?.[1]
    if (dynamicpParam) {
      if (dynamicpParam == 'dwdm') {
        params[key] = dynamicParamsStore.dynamicParams['treeNode']?.zddm || null
      } else {
        params[key] = dynamicParamsStore.dynamicParams[dynamicpParam] || null
      }
    }
  }
  http(selectConfig.api, selectConfig.method || 'get', params).then((res) => {
    optionsData.value[selectConfig.name] = res.data || res.data.record || []
    //如果该下拉框设置了默认选中值
    if (form.value[selectConfig.name]) {
      const option = findByKey(form.value[selectConfig.name], optionsData.value[selectConfig.name])
      optionsData.value[selectConfig.name] = []
      optionsData.value[selectConfig.name].push(option)
    }
  })
}
defineExpose({
  formatParams
})
</script>

<style lang="scss" scoped>
.custom-search {
  padding: 0 12px;

  box-shadow: var(--el-box-shadow-light);
  background-color: #fff;
  border-radius: 4px;

  .form-title {
  }

  .search_title {
    position: relative;

    height: 55px;
    margin-bottom: 16px;
    padding-left: 30px;

    color: #333333;
    border-bottom: 1px solid #ebebeb;

    font-size: 20px;
    font-weight: 700;
    line-height: 55px;

    &::before {
      position: absolute;
      top: 50%;
      left: 15px;

      display: block;

      width: 4px;
      height: 20px;

      content: '';
      transform: translateY(-50%);

      border-radius: 10px;
      background-color: #409eff;
    }
  }

  ::v-deep(.el-form) {
    padding-top: 12px;
    flex: 1;
    display: grid;

    border-radius: 4px;

    grid-template-columns: repeat(v-bind(columns), minmax(0, 1fr));

    row-gap: 8px;

    .el-form-item {
      // border: 1px solid blueviolet;
      margin-bottom: 12px !important;
      .el-form-item__label {
        height: 100%;
        display: flex;
        align-items: center;
        // height: v-bind(itemHeight);
        // line-height: v-bind(itemHeight);
        background-color: var(--labelBgColor);
        font-size: v-bind(fontSize);
        color: v-bind(fontColro);
      }
      .el-form-item__content {
        height: 100%;

        > div {
          width: 100%;
        }

        .el-select__selected-item {
          font-size: v-bind(fontSize);
        }

        .el-select,
        .el-select__wrapper,
        .el-input,
        .el-date-editor,
        .el-cascader {
          height: 100%;
          height: v-bind(itemHeight);
          line-height: v-bind(itemHeight);
        }

        .el-input__inner,
        .el-range-input,
        .el-select__selected-item {
          font-size: v-bind(fontSize);
          color: v-bind(fontColro);
        }
        .el-select__placeholder.is-transparent,
        .el-range-separator {
          color: #a8abb2;
        }
        .el-select-dropdown__item {
          font-size: 20px;
          color: red;
        }
        .el-form-item__error {
          font-size: 14px;
          z-index: 1;
        }
        .el-input__icon {
          font-size: 20px !important;
        }
      }
      &.search-btn {
        .el-form-item__content {
          margin-left: 20px !important;
        }
      }
    }
  }
}
.search-popover {
}
</style>
<style lang="scss">
.el-picker__popper.search-bar-picker {
  overflow: visible !important;
}

.bth {
  text-align: center;
  margin-top: 10px;
}
</style>
